home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1987
/
05
/
kernel.asm
< prev
next >
Wrap
Assembly Source File
|
1987-08-07
|
15KB
|
272 lines
; Source code for TSR, by John J. Newlin, Page 28, Volume 5.5,
; Programmer's Journal
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RAM resident KERNEL driver for main program in expanded memory
;Copyright 1987 by John J. Newlin, 4060-228 Rosenda Court, San
;Diego, CA 92122
;All rights reserved
;Assemble with MASM, link with LINK, convert to .COM with EXE2BIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Equates referencing offset addresses in the main program. Addresses
;derived from Turbo Pascal main program - see article text.
activate equ 2D9FH
demo_main equ 2DA6H
emm_handle equ 2DAAH
loaded_in_emm equ 2DA8H
code segment
assume cs:code
org 100h
begin:
jmp initialize ;jump directly to initialization code
demo LABEL DWORD ;label for far call to main prog
demo_ofs dw 0 ;offset of main prog handler
demo_seg dw 0 ;segment of main prog
i16 LABEL DWORD ;label for far call/jump to int 16h
i16_ofs dw 0 ;offset of original int 16h
i16_seg dw 0 ;segment of original int 16h
save_ss dw 0 ;save caller's SS reg
save_sp dw 0 ;save caller's SP reg
save_ax dw 0 ;save caller's AX reg
hotkey db 0 ;hotkey value
active db 0 ;active flag
handle dw 0 ;EMM handle
local_stack dw 20 dup(0) ;local stack area
stkptr dw 0 ;local SP
save_map: push ax
push dx
mov dx,cs:handle ;DX gets our handle
mov ah,47h ;save mapping context
int 67h ;call EMM
pop dx
pop ax
ret ;
restore_map:
push ax
push dx
mov dx,cs:handle ;DX gets handle
mov ah,48h ;to restore mapping context
int 67h ;call EMM
pop dx
pop ax
ret
map_memory:
push ax
push bx
push cx
push dx
mov cx,4 ;will map 4 pages
do_again: mov dx,cs:handle ;DX gets handle
mov bx,cx ;BX gets logical page
mov al,cl ;AL gets physical page
dec bx ;decrement logical page
dec al ;decrement physical page
mov ah,44h ;set up for EMM call
int 67h ;call EMM
loop do_again ;do again (3,2,1,0)
pop ax
pop bx
pop cx
pop dx
ret ;
run_demo:
call save_map ;save mapping context
call map_memory ;map our pages in
mov cs:active,1 ;set active flag
mov cs:save_ax,ax ;save AX reg
cli ;turn off interrupts
mov cs:save_ss,ss ;save caller's SS reg
mov cs:save_sp,sp ;save caller's SP reg
mov ax,cs ;get our CS
mov ss,ax ;put in SS
mov ax,offset cs:stkptr ;get offset of local stack
mov sp,ax ;put in SP
sub sp,2 ;decrement SP
sti ;enable interrupts
push ax ;save
push bx ; caller's
push cx ; regs
push dx ; on
push di ; our
push si ; local
push bp ; stack
push es ;
call cs:[demo] ;call our main prog
pop es ;restore
pop bp ; caller's
pop si ; regs
pop di ; from
pop dx ; our
pop cx ; local
pop bx ; stack
pop ax ;
cli ;turn off interrupts
mov ax,cs:save_ss ;get caller's SS reg
mov ss,ax ;put in SS
mov sp,cs:save_sp ;restore caller's SP
mov ax,cs:save_ax ;restore caller's AX
sti ;enable interrupts
mov cs:active,0 ;reset active flag
call restore_map ;restore mapping context
ret ;return
int16 proc far ;use far attr for returns
cmp ah,98h ;regular int 16 request?
jb keys16 ;yes
n00: cmp ah,9Fh ;request to remove?
jne l1 ;no
mov ax,cs:demo_seg ;yes, prepare to remove
mov es,ax ;ES gets frame segment
mov ah,45h ;prepare to release EM
mov dx,cs:handle ;load handle in DX
int 67h ;call EMM to release
cli ;turn of interrupts
push ds ;save DS
mov ax,cs:i16_seg ;get orginal int 16h seg
mov ds,ax ;put in DS
mov dx,cs:i16_ofs ;DX = original int 16h ofs
mov ax,2516h ;set up to re-install
int 21h ;call DOS to do it
pop ds ;restore ds
mov bx,2Ch ;2Ch in PSP has segment
mov ax,cs:[bx] ;get mem block segment
mov es,ax ;put in ES for DOS
mov ah,49h ;set up to release
int 21h ;call DOS to release
mov ax,cs ;our segment
mov es,ax ;put in ES for DOS
mov ah,49h ;set up to release
int 21h ;call DOS to release
sti ;enable interrupts
mov ah,4Ch ;set up to teminate
int 21h ;call DOS to terminate
l1:
cmp ah,9Bh ;requ for presence flag?
jne keys16 ;no
mov ax,0ABCDh ;indicator in AX
iret ;return to caller
no_action16:
jmp cs:[i16] ;jmp to original int 16h
keys16:
cmp cs:active,1 ;is demo active?
je no_action16 ;yes - depart
cmp ah,1 ;buffer status req?
ja no_action16 ;no - depart
je checkchar ;yes - process
getchar: mov ah,0 ;set up to get a char
pushf ;to fake int call
call cs:[i16] ;call original int 16h
cmp al,0 ;alt key pressed?
jne exit0 ;no - depart
cmp ah,cs:hotkey ;our hot key?
je action1 ;yes - process
exit0: iret ;no - return to caller
action1:
call run_demo ;call our main prog
jmp getchar ;go check key buffer
checkchar:
mov ah,1 ;set up to check buffer
pushf ;to fake int call
call cs:[i16] ;call original int 16h
pushf ;save flags
jz exit16 ;no key in buffer - depart
cmp al,0 ;alt key pressed?
jne exit16 ;no - depart
cmp ah,cs:hotkey ;our hot key pressed?
jne exit16 ;no - depart
mov ah,0 ;remove key from buffer
call cs:[i16] ;call original int 16h
call run_demo ;call our main prog
jmp checkchar ;go check buffer
exit16:
popf ;discard flags
ret 2 ;return to caller
int16 endp
initialize proc
mov ax,cs ;get code seg value
mov ds,ax ;set DS to same
continue: mov ah,9Bh ;set up for int 16 query
int 16h ;call it
cmp ax,0ABCDh ;is DEMO loaded?
jne not_loaded ;no, continue
mov dx,offset loaded_msg ;yes, it's loaded
mov ah,9 ;set up to write msg
int 21h ;write it
mov ah,4Ch ;terminate
int 21h
not_loaded: mov ax,3567h ;set up to get int 67h seg
int 21h ;call DOS
mov di,10 ;offset of EMM string
mov si,offset emm_name ;offset of our string
mov cx,8 ;8 chars to check
cld ;set direction flag forward
repz cmpsb ;compare string
jz emm_ok ;compare ok?
mov dx,offset emm_msg ;no
mov ah,9 ;set up for error msg
int 21h ;call DOS to write
mov ah,4Ch ;set up to terminate
int 21h ;terminate
emm_ok: mov ah,41h ;set up to get EMM segment
int 67h ;call EMM
mov cs:demo_seg,bx ;save it
mov es,bx ;put it in ES
mov ax,es:[loaded_in_emm] ;get DEMO flag
cmp ax,9876h ;is it there?
je demo_present ;yes
mov dx,offset not_loaded_msg ;no
mov ah,9 ;set up for error msg
int 21h ;call DOS to write
mov ah,4Ch ;set up to terminate
int 21h ;terminate
demo_present: mov al,byte ptr es:[activate] ;get hot key
mov hotkey,al ;save it
mov ax,word ptr es:[emm_handle] ;get EMM handle
mov handle,ax ;save it
mov ax,word ptr es:[demo_main];get DEMO handler offset
mov demo_ofs,ax ;save it
mov ax,3516h ;set up to get int16 addr
int 21h ;call DOS to get it
mov i16_seg,es ;save segment
mov i16_ofs,bx ;save offset
mov ax,2516h ;set up to replace with ours
mov dx,offset int16 ;offset into DX
int 21h ;call DOS to install
mov dx,offset sign_on ;sign on msg offset
mov ah,9 ;set up to write
int 21h ;call DOS to write
mov dx,offset initialize ;last byte of resident code
int 27h ;terminate & stay resident
emm_name db 'EMMXXXX0',0
emm_msg db 'No EMM available - aborting',7,'$'
loaded_msg db 'KERNEL in memory - aborting',7,'$'
sign_on db 'KERNEL is loaded and DEMO is operational in EMS','$'
not_loaded_msg db 'DEMO not in expanded memory',7,'$'
initialize endp
code ends
end begin